package cate.game.role.res.magiccontract;

import cate.common.table.activity.magiccontract.row.MagicContractBaseRow;
import cate.common.table.activity.magiccontract.row.MagicContractUnlockRow;
import cate.common.table.d.GDFunc;
import cate.common.util.GameResult;
import cate.game.attr.FightAttr;
import cate.game.role.FuncOpenChecker;
import cate.game.role.Role;
import cate.game.role.bag.hero.Hero;
import cate.game.role.res.magiccontract.msg.MagicContractInfoResp;
import easy.java.dev.note.NoteField;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RoleMagicContract extends FuncOpenChecker {

    @NoteField("key:阵营，value:灵契台")
    public Map<Integer, MagicContractDesk> deskMap;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (deskMap == null) {
            deskMap = new HashMap<>();
        }
        deskMap.values().forEach(desk -> desk.initialize(role));
    }


    @Override
    public boolean customizeCheckOpen() {
        MagicContractBaseRow row = role.getGame().table.magicContract.base.get(1);
        return role.getBag().hero.getList().stream().anyMatch(hero -> {
            if (hero != null && hero.getTpl(role.toPlayBuildContext()) != null) {
                return hero.getTpl(role.toPlayBuildContext()).star >= row.openStar;
            }
            return false;
        });
    }

    @Override
    public int getFuncId() {
        return GDFunc.MAGIC_CONTRACT;
    }

    @Override
    public void onAfterOpen() {
        initMap();
    }

    public GameResult<RoleMagicContract> putHero(int camp, int pos, String uid) {
        GameResult<RoleMagicContract> r = new GameResult<>();
        r.data = this;
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        MagicContractBaseRow baseRow = findBaseRow();
        if (baseRow == null) {
            return r.fail("基础配置不存在");
        }
        MagicContractDesk desk = deskMap.get(camp);
        if (desk == null) {
            return r.fail("此阵营不存在灵契");
        }
        Hero hero = findHero(uid);
        if (hero == null) {
            return r.fail("英雄不存在");
        }
        byte heroCamp = hero.getTpl(role.toPlayBuildContext()).camp;
        if (heroCamp != camp && heroCamp <= baseRow.campNum) {
            return r.fail("阵营不匹配");
        }
        GameResult<?> result = desk.putHero(pos, hero, baseRow);
        if (!result.ok()) {
            return r.fail(result);
        }
        role.getBase().updatePower();
        return r;
    }

    public GameResult<RoleMagicContract> offHero(int camp, int pos) {
        GameResult<RoleMagicContract> r = new GameResult<>();
        r.data = this;
        if (!isOpen()) {
            return r.fail("功能未开启");
        }
        MagicContractBaseRow baseRow = findBaseRow();
        if (baseRow == null) {
            return r.fail("基础配置不存在");
        }
        MagicContractDesk desk = deskMap.get(camp);
        if (desk == null) {
            return r.fail("此阵营不存在灵契");
        }
        GameResult<?> result = desk.offHero(pos);
        if (!result.ok()) {
            return r.fail(result);
        }
        role.getBase().updatePower();
        return r;
    }


    public void initMap() {
        MagicContractBaseRow row = findBaseRow();
        for (int i = 1; i <= row.campNum; i++) {
            deskMap.put(i, new MagicContractDesk(role));
        }
        noticeUpdate();
    }

    public void updateMap(int level) {
        List<MagicContractUnlockRow> unlockList = findUnlockList();
        boolean unlock = unlockList.stream().anyMatch(row -> row.unlockLevel > 0 && row.unlockLevel <= level);
        if (!unlock) {
            clear();
            noticeUpdate();
        }
    }

    public void clear() {
        deskMap.values().forEach(MagicContractDesk::clear);
    }

    public MagicContractBaseRow findBaseRow() {
        return role.getGame().table.magicContract.base.get(1);
    }

    public List<MagicContractUnlockRow> findUnlockList() {
        return role.getGame().table.magicContract.unlock.list;
    }

    private Hero findHero(String heroUid) {
        if (StringUtils.isBlank(heroUid)) {
            return null;
        }
        return role.getBag().hero.getItem(heroUid);
    }

    public FightAttr addAttr() {
        FightAttr f = new FightAttr();
        deskMap.values().forEach(desk -> {
            f.add(desk.addAttr());
        });
        return f;
    }

    public void noticeUpdate() {
        role.sendNow(new MagicContractInfoResp(this));
    }
}
